﻿#region Using directives

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Diagnostics;

using ApplicationLibrary.ExtendedControls;

#endregion

using ApplicationLibrary.SqlConnector;
using Microsoft.Reporting.WinForms;
using CrystalDecisions.CrystalReports.Engine;
using CrystalDecisions.Shared;
using ApplicationLibrary.Preferences;

namespace ApplicationLibrary.DBManager
{
    public partial class ReportForm : WinFormsUI.Docking.DockContent
    {
        #region Private

        private string formName = string.Empty;

        protected string ConnectionString { get; private set; }

        public ProviderType providerType { get; private set; }

        private DBMode BatchStatus = DBMode.Browse;
        private ReportClass myReport = null;
        private Dictionary<string, ParameterValues> ParameterList = null;
        private PreferencesManager<PrinterPref> myPrinter = null;
        private PrinterPref pPref = null;
        private printerForm.PrintMode printMode;
        private List<string> clickableColumn = new List<string>();

        private bool userStopBatch;

        protected Control keyControl = null;
        protected DBManager dbManager = null;
        internal ControlBinder controlBinder;

        #endregion

        #region Properties

        public bool IsNew { get; private set; }

        public Control KeyControl { get { return keyControl; } }

        public bool SilentMode { set { if (dbManager != null) dbManager.SilentMode = value; } }

        public bool ShowCopies
        {
            set
            {
                tslCopies.Visible = value;
                tsnCopies.Visible = value;
            }

            get
            {
                return tsnCopies.Visible;
            }
        }

        #endregion

        #region Events & Delegate

        public delegate void PostFormLoadEventHandler(object sender, DBManager dbManager);

        public event PostFormLoadEventHandler PostLoaded;

        public delegate bool ToolbarButtonEventHandler(ToolStripButton sender);

        public delegate bool ToolbarSplitButtonEventHandler(ToolStripSplitButton sender);

        public event ToolbarButtonEventHandler OnEnableToolbarButtons;

        //public event ToolbarSplitButtonEventHandler OnEnableToolbarSplitButtons;
        public delegate void OpenFormEventHandler(WinFormsUI.Docking.DockContent frm, bool modal);

        public event OpenFormEventHandler OpenForm;

        #endregion

        #region Virtual Function

        protected virtual void OnAttachData()
        {
        }

        protected virtual void OnBatchExecute(string reportName)
        {
        }

        protected virtual bool OnBeforeBatchExecute()
        {
            return true;
        }

        protected virtual void OnDisableControlsForRun()
        {
        }

        protected virtual void OnBindData()
        {
        }

        protected virtual void OnDoubleClickColumn(string column, string value)
        {
        }

        #endregion

        public ReportForm()
        {
            InitializeComponent();
        }

        public ReportForm(string formname)
        {
            ConnectionString = GlobalInfo.DBaseInfo.dbManager.DB_ConnectionString;
            this.providerType = GlobalInfo.LoginInfo.ProviderType;
            formName = formname;
            InitializeComponent();
            controlBinder = new ControlBinder();
            OnCustomizeToolbar(tspdbForm);

            myPrinter = new PrinterPreferencesManager(formname);
            pPref = myPrinter.ReadPreference();

            foreach (String printer in System.Drawing.Printing.PrinterSettings.InstalledPrinters)
                tscPrinter.Items.Add(printer.ToString());

            if (pPref != null)
            {
                tscPrinter.Text = pPref.Letter.PrinterName;
                tsnCopies.Text = pPref.Letter.NumPage.ToString();
                tsbCollate.Checked = pPref.Letter.Collate;
            }
        }

        public void AddClickableColumn(iColumn column)
        {
            if (!clickableColumn.Contains(column.Name))
                clickableColumn.Add(column.Name);
        }

        protected virtual void OnCustomizeToolbar(ToolStrip toolstrip)
        {
        }

        protected override void OnLoad(EventArgs e)
        {
            OnAttachData();
            if (controlBinder != null)
                controlBinder.Enable(true);

            OnBindData();

            ManageToolbarEvents();
            OnDisableControlsForRun();

            OnAddSplitMenuButton();

            if (PostLoaded != null)
            {
                PostLoaded(this, dbManager);
                ManageOperationButton();
            }

            base.OnLoad(e);
        }

        protected bool UserStopBatch()
        {
            Application.DoEvents();
            return userStopBatch;
        }

        private void formDB_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Escape)
            {
                e.Handled = true;
            }
        }

        private void formDB_KeyUp(object sender, KeyEventArgs e)
        {
            switch (e.KeyData)
            {
                case Keys.F12:
                    if (tbnPreview.Enabled)
                        OnStartPrintEvent("");
                    break;
            }
        }

        private void formDB_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            e.Cancel = OnBeforeClosing();
        }

        /// <summary>
        /// Only For Enable/Disable Controls
        /// </summary>
        public Binding BindControl(Control control)
        {
            controlBinder.Bind(control);
            return null;
        }

        public void ShowDialog(bool visible)
        {
            base.ShowDialog();
            this.Visible = visible;
        }

        #region virtual override function

        protected virtual bool OnBeforeClosing()
        {
            return false;
        }

        protected virtual bool OnPrintDocument(string sender, printerForm pf)
        {
            return true;
        }

        private void OnStartPrintEvent(string reportName)
        {
            if (!this.Validate())
                return;

            if (OnBeforeBatchExecute())
            {
                userStopBatch = false;
                BatchStatus = DBMode.Run;
                ManageToolbarEvents();
                this.Cursor = System.Windows.Forms.Cursors.WaitCursor;
                Application.DoEvents();
                ClearParameters();
                OnBatchExecute(reportName);
                this.Cursor = System.Windows.Forms.Cursors.Default;
                BatchStatus = DBMode.Browse;
                ManageToolbarEvents();
                OnDisableControlsForRun();
            }
        }

        private void OnStopPrintEvent()
        {
            userStopBatch = MessageBox.Show("Do you want stop process ?", "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == System.Windows.Forms.DialogResult.Yes;
        }

        #endregion

        #region Enable Disable Controls

        protected virtual void ManageControls(System.Windows.Forms.Control.ControlCollection controls)
        {
            bool enabled = BatchStatus != DBMode.Run;

            foreach (Control ctrl in controls)
            {
                Debug.WriteLine(string.Format("valido {0}", ctrl.GetType().ToString()));
                if (ctrl.Controls.Count != 0 && ctrl.GetType().BaseType != typeof(ExtendedDataGridView))
                    ManageControls(ctrl.Controls);

                if (
                    ctrl.GetType() == typeof(DBCheckBox) ||
                    ctrl.GetType() == typeof(RadioButton) ||
                    ctrl.GetType() == typeof(Button) ||
                    ctrl.GetType() == typeof(ComboBox) ||
                    ctrl.GetType() == typeof(DateTimePicker) ||
                    ctrl.GetType() == typeof(RadarTextBox) ||
                    ctrl.GetType() == typeof(TextBox) ||
                    ctrl.GetType() == typeof(TextBox) ||
                    ctrl.GetType() == typeof(DataGridView) ||
                    ctrl.GetType() == typeof(TabPage) ||
                    ctrl.GetType() == typeof(MaskedTextBox) ||
                    ctrl.GetType() == typeof(NumericTextBox) ||
                    ctrl.GetType() == typeof(NumericTextBox1) ||
                    ctrl.GetType() == typeof(DataGridTextBoxColumn))
                    ctrl.Enabled = enabled;

                if (ctrl.GetType().BaseType == typeof(AFSMaskedTextBox) ||
                            ctrl.GetType() == typeof(AFSMaskedTextBox))
                    ((AFSMaskedTextBox)ctrl).ReadOnly = !enabled;
                else
                    if (ctrl.GetType().BaseType == typeof(NumericTextBox1) ||
                        ctrl.GetType() == typeof(NumericTextBox1))
                        ((NumericTextBox1)ctrl).ReadOnly = !enabled;
                    else
                        if (ctrl.GetType().BaseType == typeof(NumericTextBox) ||
                        ctrl.GetType() == typeof(NumericTextBox))
                            ((NumericTextBox)ctrl).ReadOnly = !enabled;
                        else
                            if (ctrl.GetType().BaseType == typeof(DateTextBox) ||
                            ctrl.GetType() == typeof(DateTextBox))
                                ((DateTextBox)ctrl).ReadOnly = !enabled;
                            else
                                if (ctrl.GetType().BaseType == typeof(TextBox) ||
                                ctrl.GetType() == typeof(TextBox))
                                    ((TextBox)ctrl).ReadOnly = !enabled;
                                else
                                    if (ctrl.GetType().BaseType == typeof(AFSMaskedTextBox) ||
                                    ctrl.GetType() == typeof(AFSMaskedTextBox))
                                        ((AFSMaskedTextBox)ctrl).ReadOnly = !enabled;
                                    else
                                        if (ctrl.GetType().BaseType == typeof(TextBox) ||
                                        ctrl.GetType() == typeof(TextBox))
                                            ((TextBox)ctrl).ReadOnly = !enabled;
                                        else
                                            if (ctrl.GetType().BaseType == typeof(DataGridTextBox) ||
                                            ctrl.GetType() == typeof(DataGridTextBox))
                                                ((DataGridTextBox)ctrl).ReadOnly = !enabled;
                                            else
                                                if (ctrl.GetType().BaseType == typeof(DataGrid) ||
                                                ctrl.GetType() == typeof(DataGrid))
                                                    ((DataGrid)ctrl).ReadOnly = !enabled;
                                                else
                                                    if (ctrl.GetType().BaseType == typeof(LookUpCombo) ||
                                                ctrl.GetType() == typeof(LookUpCombo))
                                                        ((LookUpCombo)ctrl).Enabled = enabled;
                                                    else
                                                        if (ctrl.GetType().BaseType == typeof(ExtendedDataGridView) ||
                                                        ctrl.GetType() == typeof(ExtendedDataGridView))
                                                            ((ExtendedDataGridView)ctrl).ReadOnly = !enabled;
                                                        else
                                                            Debug.WriteLine(ctrl.GetType().ToString());
            }
        }

        #endregion

        #region Enable Disable OperationButton

        private void ManageOperationButton()
        {
            try
            {
                if (dbManager != null)
                {
                    bool enableResult = true;

                    //if (OnEnableToolbarButtons != null)
                    //    enableResult = OnEnableToolbarButtons(tbnGo);
                    //tbnGo.Enabled = BatchStatus != DBMode.Run && enableResult;

                    if (OnEnableToolbarButtons != null)
                        enableResult = OnEnableToolbarButtons(tbnExit);
                    tbnExit.Enabled = BatchStatus != DBMode.Run && enableResult;

                    //if (OnEnableToolbarSplitButtons != null)
                    //    enableResult = OnEnableToolbarSplitButtons(tbnPrint);
                    //else
                    //    enableResult = false;
                    //tbnPrint.Enabled = BatchStatus != DBMode.Run && enableResult;
                }
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.Message);
            }
        }

        private void ManageToolbarEvents()
        {
            ManageOperationButton();
            if (controlBinder != null)
                controlBinder.Enable(BatchStatus == DBMode.Browse);

            tssStatus.Text = BatchStatus == DBMode.Run
                                ? Properties.Resources.Doc_Running
                                : Properties.Resources.Doc_Ready;
        }

        #endregion

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>

        protected override void OnShown(EventArgs e)
        {
            base.OnShown(e);
        }

        #endregion

        #region Print

        protected virtual void OnAddSplitMenuButton()
        {
        }

        protected void AddSplitMenuButton(string text, string tag)
        {
            if (tbnPreview.Tag == null)
                tbnPreview.Tag = tag;

            ToolStripMenuItem mnu = new ToolStripMenuItem(text);
            mnu.Click += new EventHandler(mnu_Click);
            mnu.Tag = tag;
            tbnPreview.DropDownItems.Add(mnu);
        }

        private void mnu_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem mnu = (ToolStripMenuItem)sender;
            OnStartPrintEvent(mnu.Tag != null ? mnu.Tag.ToString() : "");
        }

        #endregion

        private void tbnExit_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void OnPrintEvent(string sender)
        {
            myReport.PrintOptions.PrinterName = tscPrinter.Text;
            myReport.PrintToPrinter(tsnCopies.Value, false, 0, 0);
        }

        private void tbnPreview_Click(object sender, EventArgs e)
        {
            printMode = printerForm.PrintMode.Preview;
            if (BatchStatus != DBMode.Run)
                OnStartPrintEvent("");
            else
                OnStopPrintEvent();
        }

        private void tbnPrint_ButtonClick(object sender, EventArgs e)
        {
            printMode = printerForm.PrintMode.Print;

            if (BatchStatus != DBMode.Run)
                OnStartPrintEvent("");
            else
            {
                OnStopPrintEvent();
                return;
            }
        }

        public void ShowReport(ReportClass Report, object DataSource)
        {
            myReport = Report;
            ShowReport(Report, DataSource, "", null);
        }

        public void ShowReport(ReportClass Report, object DataSource, string DetailName, object Detail)
        {
            Report.SetDataSource(DataSource);
            if (Detail != null)
                Report.Subreports[DetailName].SetDataSource(Detail);
            if (ParameterList != null)
            {
                foreach (KeyValuePair<string, ParameterValues> kvp in ParameterList)
                    Report.ParameterFields[kvp.Key].CurrentValues = kvp.Value;
            }

            if (printMode == printerForm.PrintMode.Preview)
            {
                crystalReportViewer1.ReportSource = Report;
                tabControl1.SelectedTab = tbpPrint;
            }
            else
            {
                tsbPrint_Click(this, EventArgs.Empty);
            }
        }

        public string ExportToPdf(string filename)
        {
            filename = filename.Replace(" ", string.Empty).Replace("/", "_");
            string file = System.IO.Path.ChangeExtension(System.IO.Path.Combine(System.IO.Path.GetTempPath(), filename), "pdf");
            myReport.ExportToDisk(ExportFormatType.PortableDocFormat, file);
            return file;
        }

        public void SetParameterValue(string paramName, object paramValue)
        {
            if (ParameterList == null)
                ParameterList = new Dictionary<string, ParameterValues>();

            if (ParameterList.ContainsKey(paramName))
                ParameterList.Remove(paramName);

            ParameterDiscreteValue parameterDiscreteValue = new ParameterDiscreteValue();
            parameterDiscreteValue.Value = paramValue;
            ParameterValues currentParameterValues = new ParameterValues();
            currentParameterValues.Add(parameterDiscreteValue);

            ParameterList.Add(paramName, currentParameterValues);
        }

        public void ClearParameters()
        {
            if (ParameterList != null)
                ParameterList.Clear();
        }

        private void tbnPref_Click(object sender, EventArgs e)
        {
            OnPreferenceEvent();
        }

        private void OnPreferenceEvent()
        {
            Preferences.PreferenceForm pf = new Preferences.PreferenceForm();
            OnAddPreferenceButton(pf);
            OpenForm(pf, true);
        }

        protected virtual void OnAddPreferenceButton(PreferenceForm prefForm)
        {
            prefForm.AddPanel(new PrinterPreferencePanel(formName));
            prefForm.AddPanel(new NHUnspellPreferencePanel(formName));
        }

        private void tsbPrint_Click(object sender, EventArgs e)
        {
            myReport.PrintOptions.PrinterName = tscPrinter.Text;
            myReport.PrintToPrinter(tsnCopies.Value, tsbCollate.Checked, 0,0);
        }

        private void tsbEmail_Click(object sender, EventArgs e)
        {
            Emailer.emailForm ef = new Emailer.emailForm();
            ef.LoadAddress += new Emailer.emailForm.LoadAddressEventHandler(ef_LoadAddress);
            EmailArgs emailArgs = SendEmail();
            ef.Address = emailArgs.Address;
            ef.Subject = emailArgs.Subject;
            ef.Body = emailArgs.Body;
            ef.Attachment = emailArgs.Attachment;

            ef.ShowDialog();
            ef.Close();
        }

        private void ef_LoadAddress(Emailer.emailAddress ea)
        {
            LoadAddress(ea);
        }

        protected virtual void LoadAddress(Emailer.emailAddress ea)
        {
        }

        protected virtual EmailArgs SendEmail()
        {
            EmailArgs ea = new EmailArgs();
            ea.Attachment = ExportToPdf("Attachment");
            return ea;
        }

        private void crystalReportViewer1_DoubleClickPage(object sender, CrystalDecisions.Windows.Forms.PageMouseEventArgs e)
        {
            if (clickableColumn.Contains(e.ObjectInfo.Name))
                OnDoubleClickColumn(e.ObjectInfo.Name, e.ObjectInfo.Text);
        }

        private void tsbCollate_CheckedChanged(object sender, EventArgs e)
        {
            tsbCollate.Text = tsbCollate.Checked
                                ? "1,2 1,2"
                                : "1,1 2,2";
        }
    }
}